package com.qianfeng.openapi.web.master.service.impl;

import com.qianfeng.openapi.common.enums.OpenApiEnums;
import com.qianfeng.openapi.common.exception.OpenApiEx;
import com.qianfeng.openapi.common.util.JSONUtil;
import com.qianfeng.openapi.web.master.bean.LayUITableVO;
import com.qianfeng.openapi.web.master.bean.LayUITreeVO;
import com.qianfeng.openapi.web.master.mapper.AdminUserMapper;
import com.qianfeng.openapi.web.master.pojo.AdminUser;
import com.qianfeng.openapi.web.master.pojo.Role;
import com.qianfeng.openapi.web.master.service.AdminUserService;
import com.qianfeng.openapi.web.master.service.RoleService;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.*;

@Service
@Slf4j
public class AdminUserServiceImpl implements AdminUserService {

    @Resource
    private AdminUserMapper adminUserMapper;

    @Autowired
    private RoleService roleService;

    @Autowired
    private RestTemplate restTemplate;


    @Override
    public AdminUser doLogin(String email, String password) {
        //1. 根据用户名查询用户信息
        AdminUser adminUser = adminUserMapper.findByEmail(email);

        //2. 如果查询的用户信息为null ->  用户名错误
        if(adminUser == null){
            log.info("【执行登录】 用户名错误! email = {}",email);
            throw new OpenApiEx(OpenApiEnums.LOGIN_USERNAME_ERROR);
        }

        //3. 比对密码失败(MD5+盐 shiro) -> 密码错误
        password = new Md5Hash(password, adminUser.getSalt(), 1024).toString();
        if(!password.equals(adminUser.getPassword())){
            log.info("【执行登录】 密码名错误! email = {},password = {}",email,password);
            throw new OpenApiEx(OpenApiEnums.LOGIN_PASSWORD_ERROR);
        }

        //4. 返回1.中查询的用户信息
        return adminUser;
    }

    @Override
    public LayUITableVO findLayUITableVO(Map<String, Object> parameters) throws IOException {
       /**
        通过数据库查询用户信息
        //1. 执行分页
        PageHelper.startPage((Integer)parameters.get("page"),(Integer)parameters.get("limit"));
        //2. 执行查询
        List<AdminUser> adminUserList = adminUserMapper.findByRealNameAndEmailAndStatus(parameters);
        //3. 封装PageInfo
        PageInfo<AdminUser> pageInfo = new PageInfo<>(adminUserList);
        //4. 封装LayUITableVO
        LayUITableVO vo = new LayUITableVO();
        vo.setCount(pageInfo.getTotal());
        vo.setData(pageInfo.getList());
        //5. 返回
        return vo;*/
       /**
        * 通过ES查询用户信息
        //1. 调用service工具方法,查询索引信息,返回LayUITableVO     vo
        LayUITableVO vo = elasticsearchService.searchAdminUserDocument(INDEX_NAME, parameters);

        */
       // 通过调用search模块查询ES中的用户信息    HttpClient, RestTemplate
        //1. 通过RestTemplate对象发送POST请求 http://localhost:9200/search/adminuser/search,并携带JSON数据, page,size,realName,email,status
        //1.1 请求参数
        String jsonParameter = JSONUtil.toJSON(parameters);
        //1.2 准备请求头
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setContentType(MediaType.APPLICATION_JSON_UTF8);
        //1.3 创建HttpEntity封装请求参数和请求头
        HttpEntity httpEntity = new HttpEntity(jsonParameter,httpHeaders);
        //1.4 发送请求
        String result = restTemplate.postForObject("http://localhost:9200/search/adminuser/search", httpEntity, String.class);
        //2. 返回LayUITableVO
        return JSONUtil.fromJSON(result,LayUITableVO.class);
    }

    @Override
    @Transactional
    public void save(AdminUser adminUser) throws IOException {
        //1. 生成当前用户的salt.
        String salt = UUID.randomUUID().toString().replace("-","");

        //2. 对用户的密码进行MD5加密和salt加盐
        String newPwd = new Md5Hash(adminUser.getPassword(),salt,1024).toString();
        adminUser.setSalt(salt);
        adminUser.setPassword(newPwd);

        //3. 执行添加
        int count = adminUserMapper.insertSelective(adminUser);

        //4. 判断添加是否成功!
        if(count != 1){
            // 添加失败!!!
            log.error("【添加用户信息】 添加用户信息失败!!! adminUser = {}" ,adminUser);
            throw new OpenApiEx(OpenApiEnums.USER_ADD_ERROR);
        }

        /**
         * // 保存数据到ES服务
         * elasticsearchService.addDocument(INDEX_NAME,adminUser.getId() + "", JSONUtil.toJSON(adminUser));
         */
        // 调用search服务将数据保存到ES中
        //1.1 封装请求参数
        String jsonParameters = JSONUtil.toJSON(adminUser);
        //1.2 封装请求头
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
        //1.3 封装到Entity
        HttpEntity httpEntity = new HttpEntity(jsonParameters,headers);
        //1.4 发送请求
        restTemplate.postForObject("http://localhost:9200/search/adminuser/add",httpEntity,String.class);


    }

    @Override
    @Transactional
    public void del(Integer[] ids) {
        //1. 调用mapper执行删除
        int count = adminUserMapper.updateStatusByIdIn(ids);

        //2. 判断count
        if(count != ids.length){
            log.error("【批量删除用户】 删除用户信息失败!! ids = {}", Arrays.toString(ids));
            throw new OpenApiEx(OpenApiEnums.USER_DEL_ERROR);
        }
    }

    @Override
    public List<LayUITreeVO> findRolesByUserId(Integer userId) {
        //1. 查询全部的角色信息
        List<Role> roles = roleService.findAll();   // 4个角色
        //2. 查询当前用户拥有的角色信息
        List<Integer> roleIds = adminUserMapper.findRoleIdByUserId(userId);

        //3. 封装数据
        List<LayUITreeVO> data = new ArrayList<>();
        for (Role role : roles) {
            LayUITreeVO vo = new LayUITreeVO();
            vo.setId(role.getId());
            vo.setTitle(role.getName());
            if(roleIds.contains(role.getId())){
                vo.setChecked(true);
            }
            data.add(vo);
        }

        //4. 返回
        return data;
    }


    @Override
    @Transactional
    public void roles(Integer userId, Integer[] roleId) {
        //1. 删除当前用户拥有的全部角色.(删除关系表)
        adminUserMapper.deleteUserRoleByUserId(userId);

        //2. 根据userId和roleId数组,添加当前用户的角色
        if(roleId != null && roleId.length > 0) {
            int count = adminUserMapper.insertUserRole(userId, roleId);
            if(count != roleId.length){
                // 给用户添加权限有问题.
                log.error("【修改用户权限】 修改用户权限失败!!! userId = {},roleId = {}",userId,Arrays.toString(roleId));
                throw new OpenApiEx(OpenApiEnums.USER_ROLE_ADD_ERROR);
            }
        }

    }

}





























